/* Grid
 *
 * Serves as a wrapper for nodes in the Astar maps.
 *
 * By: M. Etheredge
 *     S. Brattinga
 */

#include "grid.h"
#include "renderer.h"

#include <algorithm>

Grid::Grid( const int p_Width, const int p_Height )
{
	m_Width = p_Width;
	m_Height = p_Height;
}

Grid::~Grid()
{
	if( !m_Path.empty() )
	{
		m_Path.clear();
	}

	if( !m_NodesList.empty() )
	{
		m_NodesList.clear();
	}
}

void Grid::BuildList( void )
{
	int x, y;

	for( y = 0 ; y < m_Height ; ++y )
	{
		for( x = 0 ; x < m_Width ; ++x )
		{
			m_NodesList.push_back( new Astar::Node( x, y ) );
		}
	}

	Astar::InitializeMap( m_NodesList, m_Width );
}

void Grid::Render( void )
{
	int y, x, i = 0;
    char text[32];

	glBindTexture( GL_TEXTURE_2D, Renderer::g_Textures[0] );

	static const GLfloat a[] = { 0.2f, 0.2f, 1.0f, 0.8f };
	static const GLfloat b[] = { 1.0, 1.0, 1.0, 1.0 };
	static const GLfloat c[] = { 100.0 };

	glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, a );
	glMaterialfv( GL_FRONT, GL_SPECULAR, b );
	glMaterialfv( GL_FRONT, GL_SHININESS, c );

	for( y = 0 ; y < m_Height ; ++y )
	{
		for( x = 0 ; x < m_Width ; ++x )
		{
			glLoadIdentity();

			Astar::Node *n = m_NodesList.at( i++ );

			float heightN = n->GetHeight() * 0.1f;

			Renderer::g_Camera->SetView();

			glTranslatef( (x - 5) * 2.0f, heightN, (y - 20) * 2.0f );

			if( n == m_Goal || n == m_End )
			{
				glColor4f( 1.0f, 0.0f, 0.0f, 0.8f );
			}
			else if( n->GetObstacle() == true )
			{
			    glTranslatef( 0.0f, 1.0f, 0.0f );
			    glColor4f( 1.0f, 0.7f, 0.0f, 0.8f );
			}
			else if( find( m_Path.begin(), m_Path.end(), n ) != m_Path.end() )
			{
				glColor4f( 0.0f, 1.0f, 0.0f, 0.8f );
			}
			else
			{
				glColor4f( 1 - heightN,  1 - heightN,  1 - heightN, 0.8f );
			}

			glCallList( Renderer::g_CubeList );

			//Render distance
			itoa(n->GetCumulativeCost(), text, 10);
			text[strlen(text)+1] = '\0';
			glLineWidth(2.0f);
            glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

			glTranslatef(-0.3f, -1.1f, -0.3f);
			glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
            glScalef(0.005f, 0.005f, 0.005f);
			Renderer::StrokeString(GLUT_STROKE_ROMAN, text);
            glScalef(200.0f, 200.0f, 200.0f);
            glRotatef(90.0f, -1.0f, 0.0f, 0.0f);
            glTranslatef(0.3f, 1.1f, 0.3f);
            glLineWidth(1.0f);
		}
	}
}

void Grid::SetGoal( const int p_X, const int p_Y )
{
	m_Goal = m_NodesList.at( m_Width * p_Y + p_X );
}

void Grid::SetEnd( const int p_X, const int p_Y )
{
	m_End = m_NodesList.at( m_Width * p_Y + p_X );
}
